package com.CMUBiS;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.CMUBiS.Data.GlobalVars;
import com.CMUBiS.util.Item;

@WebServlet(name="BuyItemServlet", urlPatterns="/buyitem")
public class BuyItemServlet extends HttpServlet{
	private static final long serialVersionUID = 6475041056023438743L;
	private static final String EMPTY = "";
	
	/**
	 * 
	 * @param request
	 * @param response
	 * @throws ServletException
	 * @throws IOException
	 */
	public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		if(GlobalVars.isHTML4){
		
		StringBuffer errorString = new StringBuffer();
		Map<String, String[]> paramMap = request.getParameterMap();
		
		
		int userID=-1;
		String authToken=null;
		int itemID=-1;
		
		// If the have not entered a credit card number then they have not filled out the form
		if(paramMap.containsKey("creditCard")){
			/*
			 * Check the userID is present and correct
			 */
			if(!paramMap.containsKey("userID") || request.getParameter("userID").equals(EMPTY)){
					errorString.append("You must provide a userID. <br />");
			}
			else{
				// make sure the userID is a number
				try{
					userID = Integer.parseInt(request.getParameter("userID"));
					
					if(userID <0)
						errorString.append("The userID must be greater than zero <br />");
				}
				catch(Exception e){
					errorString.append("The userID must be a number. <br />");
				}
			}
			
			/*
			 * Check the auth token is passed
			 */
			if(!paramMap.containsKey("authToken") || request.getParameter("authToken").equals(EMPTY)){
				errorString.append("You must provide an auth token. <br />");
			}
			else
				authToken = request.getParameter("authToken");
			
			/*
			 * Check the credit card number
			 */
			if(!paramMap.containsKey("creditCard") || request.getParameter("creditCard").equals(EMPTY)){
				errorString.append("You must provide a credit card number. <br />");
			}
			else{
				String number = request.getParameter("creditCard");
				
				//TODO: credit card number check
				final int[][] sumTable = {{0,1,2,3,4,5,6,7,8,9},{0,2,4,6,8,1,3,5,7,9}};
			    int sum = 0, flip = 0;
			 
			    try{
				    for (int i = number.length() - 1; i >= 0; i--) {
				      sum += sumTable[flip++ & 0x1][Character.digit(number.charAt(i), 10)];
				    }
			    }
			    catch(Exception e){
			    	errorString.append("The number is formatted incorrectly<br />");
			    }
			    //return sum % 10 == 0;
			    if(!(sum % 10 == 0)) errorString.append("The number you entered is not a real credit card number <br />"); 
			    //else errorString.append("The number is correct<br />");
			}
				
				
			
			/*
			 * Check the the Item ID is valid and that no one has bought the item
			 */
			if(paramMap.containsKey("itemID")){
				// Make sure the itemID is not blank
				if(!request.getParameter("itemID").equals(EMPTY)){
					// Make sure the itemID is a number
					try{
						itemID = Integer.parseInt(request.getParameter("itemID"));
						
						//TODO: decide how an item is bought
						
						/*
						// Make sure the auction is still going
						Date endDate = GlobalVars.db.getItemEndDate(itemID);
						Date now = new Date();
						
						if(endDate.before(now)){
							errorString.append("Sorry, bidding on that item has finished. Better luck next time. <br />");
						}
						
						// If the end time is okay now, then we will enter the users bid (if all the other info is okay)
						// Even though the end time may tick past while we're doing the next part of the processing
						// they have submitted their bid on time
						else{
							itemExists = true;
						}*/
					}
					catch(Exception e){
						errorString.append("The item ID you passed is not a number. <br />");
					}
				}
				else{
					errorString.append("The item ID cannot be empty. <br />");
				}
			}
			else{
				errorString.append("You cannot bid unless you tell us which item. <br />");
			}
			
			//TODO: check quantity
			
			//TODO: how to get item value? how to we know if they won the bid or are buying now? flag?
			
			// If there are no errors the user can buy the item
			if(errorString.toString().equals("")){
				// Check the userID and authToken are correct
				if(GlobalVars.db.checkAuthToken(userID, authToken)){
					// Buy the item
					//GlobalVars.db.buyItemNow(userID, itemID, 1, 44, 12.9f);
					
					//TODO: check the feedback to make sure it was bought
					
					System.out.println("Bought it!: " + GlobalVars.db.buyItemNow(userID, itemID, 1, 44));
					
					// forward to you have bid!
					//response.sendRedirect("./confirmbuy?userID="+userID+"&authToken="+authToken);
					
				}
				else
					errorString.append("Your userID and authToken don't match. (userID: "+ userID + ", authToken: " + authToken + "<br />");
			}
		}
		
		// If we get to here then there must be an error
		this.makePage(request, response, errorString.toString());
		}else{
			PrintWriter out = response.getWriter();
			Boolean success = GlobalVars.db.buyItemNow(Integer.parseInt(request.getParameter("userID")), Integer.parseInt(request.getParameter("itemID")), Integer.parseInt(request.getParameter("quantity")), Integer.parseInt(request.getParameter("accountID")));
			if(success){
				out.println("{\"itemID\":\""+request.getParameter("itemID")+"\",\"quantity\":\""+request.getParameter("quantity")+"\"}");
			}else{
				out.println("{\"itemID\":\""+request.getParameter("itemID")+"\",\"quantity\":\"0\"}");
			}
		}
	}
	
	/**
	 * 
	 * @param request
	 * @param response
	 * @throws ServletException
	 * @throws IOException
	 */
	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		if(GlobalVars.isHTML4){
		makePage(request, response, "");
	}else{
		PrintWriter out = response.getWriter();
		Boolean success = GlobalVars.db.buyItemNow(Integer.parseInt(request.getParameter("userID")), Integer.parseInt(request.getParameter("itemID")), Integer.parseInt(request.getParameter("quantity")), Integer.parseInt(request.getParameter("accountID")));
		if(success){
			out.println("{\"itemID\":\""+request.getParameter("itemID")+"\",\"quantity\":\""+request.getParameter("quantity")+"\"}");
		}else{
			out.println("{\"itemID\":\""+request.getParameter("itemID")+"\",\"quantity\":\"0\"}");
		}
	}
	}
	
	/**
	 * 
	 * @param request
	 * @param response
	 * @param errorString
	 * @throws ServletException
	 * @throws IOException
	 */
	public void makePage(HttpServletRequest request, HttpServletResponse response, String errorString)  throws ServletException, IOException {
		// We are using PrintWriter to be friendly to the international community. PrintWrite auto-converts coding
		PrintWriter out = response.getWriter();
		

		// Do HTML4 or 5 depending on the global variables
		if(GlobalVars.isHTML4){
			// Include header
			out.println("<HTML>");
			out.println("<HEAD><TITLE>Buy Item</TITLE></HEAD>");
			out.println("<BODY>");
			out.println(errorString);
			
			createHTML4(request, response, out);
		}else{
			createHTML5(request, response, out);
		}
	}
	
	/**
	 * 
	 * @param request
	 * @param response
	 * @param out
	 * @return
	 */
	public HttpServletResponse createHTML4(HttpServletRequest request, HttpServletResponse response, PrintWriter out){
		try{
			// Set the return type
			response.setContentType("text/html");
			
			// Get the URL parameters if any were passed
			Map<String, String[]> paramMap = request.getParameterMap();
			
			// Get the userID and auth token
			String userID=null;
			String authToken=null;
			int itemID=-1;
			Item currentItem=null;
			
			if(paramMap.containsKey("userID")){
				userID = request.getParameter("userID");
			}
			
			if(paramMap.containsKey("authToken")){
				authToken = request.getParameter("authToken");
			}
			
			// Get the itemID
			if(paramMap.containsKey("itemID")){
				if(!request.getParameter("itemID").equals(EMPTY)){
					// Make sure the itemID is a number
					try{
						itemID = Integer.parseInt(request.getParameter("itemID"));
						
						currentItem = GlobalVars.db.getItem(itemID, Boolean.TRUE);
					}
					catch(Exception e){ }
				}
			}
			
			if(currentItem!=null){
				/*
				 * Print the items description
				 */
				out.println("Item: " + currentItem.getDescription());
				out.println("Price: " + currentItem.getBuyNowPrice());
				
				/*
				 * Let the user enter their payment details
				 */
				out.println("<form name=\"buy\" action=\"buyitem\" method=\"POST\">");
				out.println("<div id=\"center\">");	
				
				if(userID != null)
					out.println("<input type=\"hidden\" name=\"userID\" value=\""+userID+"\">");
				if(authToken != null)
					out.println("<input type=\"hidden\" name=\"authToken\" value=\""+authToken+"\">");
				
				out.println("<input type=\"hidden\" name=\"itemID\" value=\""+itemID+"\">");
				
				// Make the credit card box box
				out.println("<div id=\"floatright\">Name on card</div>");
				out.println("<div id=\"floatcenter\"> <input type=\"text\" name=\"name\" size=\"30\" value=\""+ (paramMap.containsKey("name") ?  request.getParameter("name") : "") + "\"/> </div>");
				
				
				out.println("<div id=\"floatright\">Credit Card Number: (5500000000000004)</div>");
				out.println("<div id=\"floatcenter\"> <input type=\"text\" name=\"creditCard\" size=\"30\" value=\""+ (paramMap.containsKey("creditCard") ?  request.getParameter("creditCard") : "") + "\"/> </div>");
				
				out.println("<div id=\"floatright\">CVV2 code</div>");
				out.println("<div id=\"floatcenter\"> <input type=\"text\" name=\"cvv\" size=\"30\" value=\""+ (paramMap.containsKey("cvv") ?  request.getParameter("cvv") : "") + "\"/> </div>");
				
				
				out.println("<div id=\"floatright\"><input type=\"submit\" value=\"Buy Now\"></div>");
				
				out.println("</div>");
				out.println("</form>");
			}
			else{
				out.println("Bad item");
			}
			
			// Include footer
			out.println("</BODY></HTML>");
		}
		catch(Exception e){
			e.printStackTrace();
		}
		
		return response;
	}
	
	public HttpServletResponse createHTML5(HttpServletRequest request, HttpServletResponse response, PrintWriter out){
		try{
			// Set the return type
			response.setContentType("text/html");
			
			// Get the URL parameters if any were passed
			Map<String, String[]> paramMap = request.getParameterMap();
			
			// Get the userID and auth token
			String userID=null;
			String authToken=null;
			int itemID=-1;
			Item currentItem=null;
			
			if(paramMap.containsKey("userID")){
				userID = request.getParameter("userID");
			}
			
			if(paramMap.containsKey("authToken")){
				authToken = request.getParameter("authToken");
			}
			
			// Get the itemID
			if(paramMap.containsKey("itemID")){
				if(!request.getParameter("itemID").equals(EMPTY)){
					// Make sure the itemID is a number
					try{
						itemID = Integer.parseInt(request.getParameter("itemID"));
						
						currentItem = GlobalVars.db.getItem(itemID, Boolean.TRUE);
					}
					catch(Exception e){ }
				}
			}
			
			if(currentItem!=null){
				/*
				 * Print the items description
				 */
				out.println("Item: " + currentItem.getDescription());
				out.println("Price: " + currentItem.getBuyNowPrice());
				
				/*
				 * Let the user enter their payment details
				 */
				out.println("<form name=\"buy\" action=\"buyitem\" method=\"POST\">");
				out.println("<div id=\"center\">");	
				
				if(userID != null)
					out.println("<input type=\"hidden\" name=\"userID\" value=\""+userID+"\">");
				if(authToken != null)
					out.println("<input type=\"hidden\" name=\"authToken\" value=\""+authToken+"\">");
				
				out.println("<input type=\"hidden\" name=\"itemID\" value=\""+itemID+"\">");
				
				// Make the credit card box box
				out.println("<div id=\"floatright\">Name on card</div>");
				out.println("<div id=\"floatcenter\"> <input type=\"text\" name=\"name\" size=\"30\" value=\""+ (paramMap.containsKey("name") ?  request.getParameter("name") : "") + "\"/> </div>");
				
				
				out.println("<div id=\"floatright\">Credit Card Number: (5500000000000004)</div>");
				out.println("<div id=\"floatcenter\"> <input type=\"text\" name=\"creditCard\" size=\"30\" value=\""+ (paramMap.containsKey("creditCard") ?  request.getParameter("creditCard") : "") + "\"/> </div>");
				
				out.println("<div id=\"floatright\">CVV2 code</div>");
				out.println("<div id=\"floatcenter\"> <input type=\"text\" name=\"cvv\" size=\"30\" value=\""+ (paramMap.containsKey("cvv") ?  request.getParameter("cvv") : "") + "\"/> </div>");
				
				
				out.println("<div id=\"floatright\"><input type=\"submit\" value=\"Buy Now\"></div>");
				
				out.println("</div>");
				out.println("</form>");
			}
			else{
				out.println("Bad item");
			}
		}
		catch(Exception e){
			e.printStackTrace();
		}
		
		return response;
	}
}
